/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lt.cj.core;

import org.lt.cj.config.entities.ConfigModel;
import java.util.ArrayList;
import java.util.List;
import org.lt.cj.core.server.ServerModel;

/**
 * 执行任务线程组
 * @author luohong
 */
public class CrawlerThreadGroup extends ThreadGroup {

    private String name;
    private boolean isCircle = false;
    private ConfigModel configModel;
    private LinkDB linkDB;
    private int threadCount;
    private Thread deomenThread;
    private List<CrawlingThread> threadList;

    public CrawlerThreadGroup(String name) {
        super(name);
    }

    public void resumeTask(Thread[] list) {

        int length = list.length;
        for (int i = 0; i < length; i++) {

            CrawlingThread thread = (CrawlingThread) list[i];
            thread.resumeCrawler();
        }
    }

    public void pauseTask(Thread[] list) {

        int length = list.length;
        for (int i = 0; i < length; i++) {
            CrawlingThread thread = (CrawlingThread) list[i];
            thread.pause();
        }
    }

    public String stopTask() {
        String s = "task has benn stopped";
        for (int i = 0; i < threadList.size(); i++) {
            threadList.get(i).stopThread();
        }
        this.saveConfigModel();
        return s;
    }

    public void accessTaskPaper(ConfigModel configModel) {                    //接受任务
        this.configModel = configModel;
//        linkDB = new LinkDB(configModel.getSeeds());                             //存储链接入口数据，并初始化链接存储库
        linkDB = new LinkDB(configModel.getSeeds());
        threadCount = configModel.getWorkingThreads();                          //获得配置文件的线程数
        threadList = new ArrayList();
        breedCrawlers();
    }

    public void breedCrawlers() {                                             //繁殖爬虫,就是分发任务，由繁殖出来的爬虫去执行

        for (int i = 0; i < threadCount; i++) {
            CrawlingThread thread = new CrawlingThread(this, linkDB, configModel);    //创建爬虫线程
            threadList.add(thread);                                             //添加这个爬行线程的引用
            thread.start();
        }
        deomenThread = new DeomenThread(this);                                      //创建守护线程
        deomenThread.setDaemon(true);
        deomenThread.start();
    }

    public int getCurrentWorkingThreadCount() {

        int count = 0;
        for (int i = 0; i < this.threadCount; i++) {
            CrawlingThread thread = threadList.get(i);
            if (thread.isAlive()) {
                count = count + 1;
            }
        }
        return count;
    }

    public int getQueueURLCount() {

        int count = 0;
        if (!linkDB.unVisitedUrlsEmpty()) {
            count = linkDB.getQueueUnvisitedUrlCount();
        }
        return count;
    }

    public void saveConfigModel() {
        synchronized (CrawlerThreadGroup.this.linkDB) {
//            Queue<String> queue = CrawlerThreadGroup.this.linkDB.getUnVisitedUrl();
//            String[] urls = new String[queue.getCount()];
//            for (int i = 0; i < urls.length; i++) {
//                urls[i] = queue.getT(i);
//            }
//            CrawlerThreadGroup.this.configModel.setUrls(urls);
//            ServerModel serverModel = ServerModel.getInstance();
//            serverModel.saveTask(configModel);
        }
    }

    /*
     *  这个线程是这个线程组的守护线程，负责检测并保证线程组内线程的数量
     */
    class DeomenThread extends Thread {

        public DeomenThread() {
            super();
        }

        public DeomenThread(CrawlerThreadGroup group) {
            super(group, CrawlerThreadGroup.this.getName() + "_spirit");
        }

        @Override
        public void run() {

            boolean runFlag = true;
            while (runFlag) {
                try {
                    sleep(5000 * 60);
                } catch (InterruptedException ex) {
//                    Logger.getLogger(CrawlerThreadGroup.class.getName()).log(Level.SEVERE, null, ex);
                }
                Queue<Seed> queue = CrawlerThreadGroup.this.linkDB.getUnVisitedUrl();
                List<Seed> urls = new ArrayList<Seed>();
                for (int i = 0; i < urls.size(); i++) {
                    urls.add(queue.getT(i));
                }
                CrawlerThreadGroup.this.configModel.setSeeds(urls);
                ServerModel serverModel = ServerModel.getInstance();
                serverModel.saveTask(configModel);
                if (configModel.getSeeds().isEmpty()) {
//                    runFlag = false;
                }
            }
        }
    }

    public ConfigModel getConfigModel() {
        return configModel;
    }

    public void setConfigModel(ConfigModel configModel) {
        this.configModel = configModel;
    }

    public LinkDB getLinkDB() {
        return linkDB;
    }

    public void setLinkDB(LinkDB linkDB) {
        this.linkDB = linkDB;
    }
}
